package com.shenmazong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenmazong.pojo.TbUser;
import com.shenmazong.service.TbUserService;
import com.shenmazong.mapper.TbUserMapper;
import com.shenmazong.utils.ResultResponse;
import com.shenmazong.utils.TokenUtils;
import com.shenmazong.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 *
 */
@Service
@Slf4j
public class TbUserServiceImpl implements TbUserService {

    @Autowired
    TbUserMapper tbUserMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public ResultResponse userLogin(LoginVo loginVo) {
        //-- 判断用户存不存在
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUsername, loginVo.getUserName()).last("limit 1"));
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //-- 判断密码
        boolean checkpw = BCrypt.checkpw(loginVo.getPassWord(), tbUser.getPassword());

        if(!checkpw) {
            return ResultResponse.FAILED(403, "密码不正确");
        }

        //-- 生成token

        // token过期时间：redis的过期时间
        // 注意：token的过期时间建议比redis中要稍微长一点
        String token = TokenUtils.token()
                .setKey("123456")
                .setExpire(60 * 30)
                .createToken("userId", ""+tbUser.getId(), "userName", tbUser.getUsername());

        //-- 把token放到redis
        // 问题1：token的key怎么设置：userId作为key：多终端的时候，是有问题：
        // 问题2：token自动更新
        String key = "pc:"+tbUser.getId();
        redisTemplate.opsForValue().set(key, token, 30, TimeUnit.MINUTES);

        //-- 返回用户信息
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(tbUser, userInfoVo);
        userInfoVo.setToken(token);

        return ResultResponse.SUCCESS(userInfoVo);
    }

    @Override
    public ResultResponse userResetPassword(ResetPassworVo resetPassworVo) {
        // 获取用户
        TbUser tbUser = tbUserMapper.selectById(resetPassworVo.getUserId());
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        // 比较密码
        boolean checkpw = BCrypt.checkpw(resetPassworVo.getOldPass(), tbUser.getPassword());
        if(!checkpw) {
            return ResultResponse.FAILED(403, "密码不正确");
        }

        // 修改密码
        String hashpw = BCrypt.hashpw(resetPassworVo.getNewPass(), BCrypt.gensalt());
        tbUser.setPassword(hashpw);
        tbUserMapper.updateById(tbUser);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse addUser(AddUserVo addUserVo) {
        // 判断验证码
        String key = addUserVo.getMobile();
        String redisCode = (String)redisTemplate.opsForValue().get(key);
        if(redisCode == null) {
            return ResultResponse.FAILED(410, "验证码过期");
        }
        if(!redisCode.equals(addUserVo.getVerifyCode())) {
            return ResultResponse.FAILED(410, "验证码错误");
        }

        // 判断用户名是否存在(判断手机号)
        LambdaQueryWrapper<TbUser> query = new QueryWrapper<TbUser>().lambda()
                .eq(TbUser::getUsername, addUserVo.getUserName());
        query.or().eq(TbUser::getPhone, addUserVo.getMobile());
        query.last("limit 1");

        TbUser tbUser = tbUserMapper.selectOne(query);
        if(tbUser != null) {
            return ResultResponse.FAILED(410, "用户已存在");
        }

        // 开始注册
        TbUser user = new TbUser();
        user.setUsername(addUserVo.getUserName());

        // 密码加密
        String hashpw = BCrypt.hashpw(addUserVo.getUserPass(), BCrypt.gensalt());

        user.setPassword(hashpw);
        user.setPhone(addUserVo.getMobile());
        user.setCreated(new Date());
        user.setUpdated(new Date());

        tbUserMapper.insert(user);

        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse sendCode(MobileVo mobileVo) {

        // 生成随机验证码
        String code = "1234";

        // 验证码存入redis
        redisTemplate.opsForValue().set(mobileVo.getMobile(), code, 1, TimeUnit.MINUTES);

        // 调用短信发送接口
        log.info("code:"+code);

        return ResultResponse.SUCCESS();
    }
}




